package com.example.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;

import javax.sql.DataSource;


/*
   添加spring security安全框架到pom
   所有的http都需要认证
   不需要特定的角色和权限
   没有登录页面
   认证过程是通过Http basic对话认证框实现的
   系统只有一个用户User
   -------------------------------------------
   通过登录页面提示用户进行认证，而不是HTTP basic
   提供多个用户，并提供一个注册页面
   对不同的路径，执行不同的安全规则
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

 /*
  重写方法进行用户储存
  spring 提供了 基于内存的储存
  基于JDBC的储存
  基于LDAP作为后端的用户储存 Lightweight Directory Access Protocol 轻量级目录访问协议
  自定义用户详情页
  */

    // 基于内存储存用户 不能很好的编辑用户
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth                                   // 使用构造者build接口来构建细节
//                .inMemoryAuthentication()      // 指定用户信息
//                .withUser("buzz")    // 配置用户
//                .password("infinity")
//                .authorities("ROLE_USER")
//                .and()
//                .withUser("woody")
//                .password("bullseye")
//                .authorities("ROLE_USER");
//    }
//
    //基于JDBC储存， 必须设置一个dataSource，才能让其访问数据库
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//       auth
//               .jdbcAuthentication()
//               .dataSource(dataSource);
//    }

    // 用户自定义查询
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth
//                .jdbcAuthentication()
//                .dataSource(dataSource)
//                .usersByUsernameQuery("select username,password,enable from Users where username=?")
//                .authoritiesByUsernameQuery("select username,authority from UserAuthorities where username = ?")
//                .passwordEncoder(new StandardPasswordEncoder("53cr3t")); //密码加密
//    }


    // 基于LDAP 默认情况下spring的LDAP认证假设LADP服务器监听本机的33389端口，但是你的LDAP服务器如果在别的机器上可以使用contextSource（）

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .ldapAuthentication()
                .userSearchBase("ou=people")    //查找用户提供了基础查询 声明用户应在名为people的组织单元下搜素
                .userSearchFilter("{uid={0}}")
                .groupSearchBase("ou=groups")   // 查找组提供了基本查询
                .groupSearchFilter("member={0}")
                .passwordCompare()                 //密码对比 在LDAP的服务器上
                .passwordEncoder(new BCryptPasswordEncoder()) // 加密
                .passwordAttribute("passcode");                 //如果密码保存在不同的属性上，可以通过这个方法来申明密码属性;
    }

}
